#include "llib_version.h"
#define L_VERSION   1111225
#if L_VERSION == LLIB_VERSION_TO_TEST

#include <boost/test/unit_test.hpp>
using namespace boost;

#include <llib.h>
using namespace llib;
using namespace llib::geom;
using namespace llib::math;

#include <vector>
using namespace std;

BOOST_AUTO_TEST_SUITE(Equation_test_suite)

BOOST_AUTO_TEST_CASE(Equation_linear)
{
    Float A, B;

    A = 1; B = 1;
    vector<Float> res0 = EquationSolver::SolveLinearEquation(A, B);
    BOOST_CHECK_EQUAL( SZ(res0), 1 );
    BOOST_CHECK_EQUAL( res0[0], -1.f );

    A = 0; B = 50.0f;
    vector<Float> res1 = EquationSolver::SolveLinearEquation(A, B);
    BOOST_CHECK_EQUAL( SZ(res1), 0 );

    A = -42156.123f; B = 493948.35f;
    vector<Float> res2 = EquationSolver::SolveLinearEquation(A, B);
    BOOST_CHECK_EQUAL( SZ(res2), 1 );
    BOOST_CHECK_EQUAL( res2[0], 11.71712f );
}

BOOST_AUTO_TEST_CASE(Equation_quadratic)
{
    Float A, B, C, R0, R1;

    A = 1; B = 1; C = 1;
    vector<Float> res0 = EquationSolver::SolveQuadraticEquation(A, B, C);
    BOOST_CHECK_EQUAL( SZ(res0), 0 );

    A = 5; B = -10; C = 6;
    vector<Float> res1 = EquationSolver::SolveQuadraticEquation(A, B, C);
    BOOST_CHECK_EQUAL( SZ(res1), 0 );

    A = 234.67f; B = -82329.f; C = -23.4f;
    R0 = Float(-0.0002842252553011144);
    R1 = Float(350.8291076794676);
    vector<Float> res2 = EquationSolver::SolveQuadraticEquation(A, B, C);
    BOOST_CHECK_EQUAL( SZ(res2), 2 );
    BOOST_CHECK_EQUAL( res2[0], R0 );
    BOOST_CHECK_EQUAL( res2[1], R1 );

    A = 0.5f; B = 4.f; C = 8.f;
    R0 = -4.f;
    vector<Float> res3 = EquationSolver::SolveQuadraticEquation(A, B, C);
    BOOST_CHECK_EQUAL( SZ(res3), 1 );
    BOOST_CHECK_EQUAL( res3[0], R0 );

    A = 69854.3f; B = 2684.6f; C = -56465.24f;
    R0 = -0.9184920905257202f;
    R1 = 0.880060669696938f;;
    vector<Float> res4 = EquationSolver::SolveQuadraticEquation(A, B, C);
    BOOST_CHECK_EQUAL( SZ(res4), 2 );
    BOOST_CHECK_EQUAL( res4[0], R0 );
    BOOST_CHECK_EQUAL( res4[1], R1 );
}

BOOST_AUTO_TEST_CASE(Equation_cubic)
{
    Float A, B, C, D, R0, R1, R2;

    A = 1.f; B = 2.f; C = -3.f; D = -4.f;
    R0 = -2.5615528128088303f;
    R1 = -1.0000000000000002f;
    R2 = 1.5615528128088303f;
    vector<Float> res0 = EquationSolver::SolveCubicEquation(A, B, C, D);
    BOOST_CHECK_EQUAL( SZ(res0), 3 );
    BOOST_CHECK_LT( abs((res0[0] - R0) / R0), Float_Epsilon );
    BOOST_CHECK_LT( abs((res0[1] - R1) / R1), Float_Epsilon );
    BOOST_CHECK_LT( abs((res0[2] - R2)) / R2, Float_Epsilon );

    A = 10.f; B = 2.f; C = -3.f; D = -4.f;
    R0 = 0.8f;
    vector<Float> res1 = EquationSolver::SolveCubicEquation(A, B, C, D);
    BOOST_CHECK_EQUAL( SZ(res1), 1 );
    BOOST_CHECK_LT( abs((res1[0] - R0)) / R0, Float_Epsilon );

    A = 358.6f; B = -54.8f; C = 17.2f; D = 0.1564f;
    R0 = -0.00883024f;
    vector<Float> res2 = EquationSolver::SolveCubicEquation(A, B, C, D);
    BOOST_CHECK_EQUAL( SZ(res2), 1 );
    BOOST_CHECK_LT( abs((res2[0] - R0) / R0), Float_Epsilon );

    A = -34.23f; B = -0.6514f; C = 545.f; D = 334.6f;
    R0 = -3.64856f;
    R1 = -0.62911f;
    R2 = 4.25864f;
    vector<Float> res3 = EquationSolver::SolveCubicEquation(A, B, C, D);
    BOOST_CHECK_EQUAL( SZ(res3), 3 );
    BOOST_CHECK_LT( abs((res3[0] - R0) / R0), Float_Epsilon );
    BOOST_CHECK_LT( abs((res3[1] - R1) / R1), Float_Epsilon );
    BOOST_CHECK_LT( abs((res3[2] - R2) / R2), Float_Epsilon );

    A = 64.259f; B = -35684.f; C = -0.54f; D = 224.f;
    R0 = -0.0792315f;
    R1 = 0.0792276f;
    R2 = 555.315f;
    vector<Float> res4 = EquationSolver::SolveCubicEquation(A, B, C, D);
    BOOST_CHECK_EQUAL( SZ(res4), 3 );
    BOOST_CHECK_LT( abs((res4[0] - R0) / R0), Float_Epsilon );
    BOOST_CHECK_LT( abs((res4[1] - R1) / R1), Float_Epsilon );
    BOOST_CHECK_LT( abs((res4[2] - R2) / R2), Float_Epsilon );

    A = -33.f; B = 0.2125f; C = -20.21f; D = 212124.f;
    R0 = 18.5846f;
    vector<Float> res5 = EquationSolver::SolveCubicEquation(A, B, C, D);
    BOOST_CHECK_EQUAL( SZ(res5), 1 );
    BOOST_CHECK_LT( abs((res5[0] - R0) / R0), Float_Epsilon );
}



BOOST_AUTO_TEST_SUITE_END()

#endif
